#pragma once

#include "ConnectorEnd.h"

#include "ConnectableElement.h"
#include "Property.h"

namespace uml {

void ConnectorEnd::fromJson(const QJsonObject& json, QStringList& errorList) {
    if (json.isEmpty()) {
        return;
    }

    MultiplicityElement::fromJson(json, errorList);
    definingEnd_ = JsonSerializable::create<Property>(json.value("definingEnd"), errorList);

    partWithPort_ = JsonSerializable::create<Property>(json.value("partWithPort"), errorList);

    role_ = JsonSerializable::create<ConnectableElement>(json.value("role"), errorList);

}

void ConnectorEnd::toJson(QJsonObject& json) {
    MultiplicityElement::toJson(json);
    if (definingEnd_) {
        QJsonObject definingEnd_json;
        definingEnd_->toJson(definingEnd_json);
        json.insert("definingEnd", definingEnd_json);
    }
    if (partWithPort_) {
        QJsonObject partWithPort_json;
        partWithPort_->toJson(partWithPort_json);
        json.insert("partWithPort", partWithPort_json);
    }
    if (role_) {
        QJsonObject role_json;
        role_->toJson(role_json);
        json.insert("role", role_json);
    }
}

/// <summary>
/// definingEnd getter
/// A derived property referencing the corresponding end on the Association which
/// types the Connector owing this ConnectorEnd, if any. It is derived by selecting
/// the end at the same place in the ordering of Association ends as this
/// ConnectorEnd.
/// </summary>
shared_ptr<Property> ConnectorEnd::definingEnd() const {
    return definingEnd_;
}

/// <summary>
/// definingEnd setter
/// A derived property referencing the corresponding end on the Association which
/// types the Connector owing this ConnectorEnd, if any. It is derived by selecting
/// the end at the same place in the ordering of Association ends as this
/// ConnectorEnd.
/// </summary>
void ConnectorEnd::setDefiningEnd(shared_ptr<Property> value) {
    definingEnd_ = value;
}

/// <summary>
/// partWithPort getter
/// Indicates the role of the internal structure of a Classifier with the Port to
/// which the ConnectorEnd is attached.
/// </summary>
shared_ptr<Property> ConnectorEnd::partWithPort() const {
    return partWithPort_;
}

/// <summary>
/// partWithPort setter
/// Indicates the role of the internal structure of a Classifier with the Port to
/// which the ConnectorEnd is attached.
/// </summary>
void ConnectorEnd::setPartWithPort(shared_ptr<Property> value) {
    partWithPort_ = value;
}

/// <summary>
/// role getter
/// The ConnectableElement attached at this ConnectorEnd. When an instance of the
/// containing Classifier is created, a link may (depending on the multiplicities)
/// be created to an instance of the Classifier that types this ConnectableElement.
/// </summary>
shared_ptr<ConnectableElement> ConnectorEnd::role() const {
    return role_;
}

/// <summary>
/// role setter
/// The ConnectableElement attached at this ConnectorEnd. When an instance of the
/// containing Classifier is created, a link may (depending on the multiplicities)
/// be created to an instance of the Classifier that types this ConnectableElement.
/// </summary>
void ConnectorEnd::setRole(shared_ptr<ConnectableElement> value) {
    role_ = value;
}

} // namespace uml
